package com.lingCheng.avg.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingCheng.avg.controller.fo.TaskChainFo;
import com.lingCheng.avg.entity.*;
import com.lingCheng.avg.mapper.AgvTasksHisMapper;
import com.lingCheng.avg.mapper.AgvTasksMapper;
import com.lingCheng.avg.service.AgvService;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class DingShiRW {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private AgvService agvService;

    @Autowired
    private AgvTasksMapper agvTasksMapper;

    @Autowired
    private AgvTasksHisMapper agvTasksHisMapper;

    @Scheduled(fixedRate = 5000)
    public void ScheduledScanRw() throws JsonProcessingException {
        // 扫描任务表的状态
        List<AgvTasks> agvTasks = scanTaskStatus();
        if(agvTasks==null){
            log.info("暂时没有可用任务!");
        }else {// 当状态为0时调用接口
            for (AgvTasks agvTask : agvTasks) {
                callApi(agvTask);
            }
        }
    }

    /*
     * 搜索任务状态
     * */
    private List<AgvTasks> scanTaskStatus() {
        List<AgvTasks> rwState = agvService.findRwState();
        return rwState;
    }

    /*
     * 调用对方接口
     * */
    private void callApi(AgvTasks agvTasks) throws JsonProcessingException {
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
        headers.add("token", "admin123");
        headers.add("name", "lx-script");
        // 构造请求体
        TaskChainFo taskChain = new TaskChainFo();
        TaskChain task = new TaskChain();//主任务
        task.setIsReturn(1);//是否回传。
        task.setAreaId(agvTasks.getAreaId());//区域 ID。
        task.setAmrId(agvTasks.getAmrId());//车辆ID
        taskChain.setTaskChain(task);

        TaskPo taskPo1 = new TaskPo();//子任务1
        taskPo1.setTaskType(agvTasks.getTaskType1());//动作类型
        taskPo1.setMapId(agvTasks.getMapId());//地图ID
        taskPo1.setEndPointCode(agvTasks.getStartPointCode());//目标点编号

        TaskPo taskPo2 = new TaskPo();//子任务2
        taskPo2.setTaskType(agvTasks.getTaskType2());//动作类型
        taskPo2.setMapId(agvTasks.getMapId());//地图ID
        taskPo2.setEndPointCode(agvTasks.getEndPointCode());//目标点编号

        taskChain.setTasks(Arrays.asList(taskPo1, taskPo2));

        TaskPo taskPo3 = new TaskPo();
        String extend = "";
        // 目标地址要对接   入库
        if(agvTasks.getTaskType2().startsWith("BP") ){
            extend = "{\"dockName\":\""+agvTasks.getEndPointCode()+"\"}";
            String po3EndPoint = "";
//            taskPo1.setExtend(extend);
            taskPo2.setExtend(extend);

            po3EndPoint = agvTasks.getEndPointCode().startsWith("SS")?"CZD2":"CZD1";
            taskPo3.setTaskType(taskPo2.getTaskType().equals("BP100")?"BP101":"BP201");
            taskPo3.setMapId(agvTasks.getMapId());
            taskPo3.setEndPointCode(po3EndPoint);
            taskPo3.setExtend(extend);

            taskChain.setTasks(Arrays.asList(taskPo1, taskPo2, taskPo3));

        }
        // 开始地址要对接    出库
        if(agvTasks.getTaskType1().startsWith("BP")){
            extend = "{\"dockName\":\""+agvTasks.getStartPointCode()+"\"}";
            String po3EndPoint = "";
            taskPo1.setExtend(extend);
//            taskPo2.setExtend(extend);

            po3EndPoint = agvTasks.getStartPointCode().startsWith("SS")?"CZD2":"CZD1";
            taskPo3.setTaskType(taskPo1.getTaskType().equals("BP100")?"BP101":"BP201");
            taskPo3.setMapId(agvTasks.getMapId());
            taskPo3.setEndPointCode(po3EndPoint);
            taskPo3.setExtend(extend);

            taskChain.setTasks(Arrays.asList(taskPo1, taskPo3, taskPo2));

        }

        if(agvTasks.getEndPointCode().startsWith("GWXL")){
            taskPo2.setExtend("{\"high_liftup_height\":\""+385+"\"}");
            taskChain.setTasks(Arrays.asList(taskPo1, taskPo2));
        }

        HttpEntity<TaskChainFo> requestEntity = new HttpEntity<>(taskChain, headers);
        log.info(requestEntity.toString());//打印我发送的任务
        // 发送POST请求
        String url = "http://192.168.10.201:8081/task/add";
        // 处理响应数据
        String postForObject = restTemplate.postForObject(url, requestEntity, String.class);
        System.out.println(postForObject);
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(postForObject);
        long data = rootNode.get("data").asLong();
        boolean state = rootNode.get("state").asBoolean();
        int status=0;
        if (state==true){
            status=1;
        }else{
            status=2;
        }
        agvService.UpdateRWH(agvTasks.getId(), data,status);
    }

    public void GET_AGV_INFO(){
        try {
            String url = "http://192.168.10.201:8081/amr/onlineAmr";
//            String url = "http://localhost:8883/wcs3D/hoisterTest/list";
            RestTemplate rs = new RestTemplate();
            ResponseEntity<JsonData> exchange = rs.exchange(url, HttpMethod.GET,null, JsonData.class);
            JsonData jsonData = exchange.getBody();
            if (jsonData != null)
            {
                if (jsonData.getCode() != 200)
                {
                    log.info("获取AGV信息失败：{}", jsonData.getMsg());
                }
                List<Object> updateList = new LinkedList<>();
                List<Object> jsonArray = JSONArray.parseArray(JSON.toJSONString(jsonData.getData()));
                List<GetAgvinfo> agvInfoList = agvTasksMapper.getAgvInfoList();

                for(Object obj : jsonArray){
                    Map<String,Object> map = JSONObject.parseObject(JSON.toJSONString(obj),Map.class);
                    Map<String,Object> amrExceptionMap = map.containsKey("amrException") ? JSONObject.parseObject(JSON.toJSONString(map.get("amrException")),Map.class) : null;
                    Map<String,Object> coordinateMap = map.containsKey("coordinate") ? JSONObject.parseObject(JSON.toJSONString(map.get("coordinate")),Map.class) : null;

                    String device_id = map.containsKey("id")?map.get("id").toString():"";
                    String device_ip = map.containsKey("ip")?map.get("ip").toString():"";
                    String device_name = map.containsKey("name")?map.get("name").toString():"";
                    String map_id = map.containsKey("mapId")?map.get("mapId").toString():"";
                    String map_name = map.containsKey("mapName")?map.get("mapName").toString():"";
                    String area_id = map.containsKey("areaId")?map.get("area_id").toString():"";
                    String battery_percentile = map.containsKey("batteryPercentile")?map.get("batteryPercentile").toString():"";
                    String state = map.containsKey("state")?map.get("state").toString():"";
                    String state_id = map.containsKey("stateId")?map.get("stateId").toString():"";
                    String x = "0";
                    String y = "0";
                    String theta = "0";
                    String level = "";
                    int fault_rate = 0;
                    StringBuilder errorInfo = new StringBuilder();

                    List<Object> exception = new LinkedList<>();
                    if(coordinateMap!=null){
                        x = coordinateMap.containsKey("x")?coordinateMap.get("x").toString():"0";
                        y = coordinateMap.containsKey("y")?coordinateMap.get("y").toString():"0";
                        theta = coordinateMap.containsKey("theta")?coordinateMap.get("theta").toString():"0";
                    }
                    try {
                        if (amrExceptionMap != null) {
                            level = amrExceptionMap.containsKey("level") ? amrExceptionMap.get("level").toString() : "";
                            exception = amrExceptionMap.containsKey("exception") ? JSONArray.parseArray(JSON.toJSONString(amrExceptionMap.get("exception"))) : new LinkedList<>();

                            List<AgvErrorInfo> agvErrorInfoList = agvTasksMapper.getAgvErrorInfoList(device_id);
                            // 如果这次查到的异常之前还有未恢复的记录，就不做新增，如果没有记录是新的异常就新增
                            for (Object ob : exception) {
                                errorInfo.append(JSON.toJSONString(ob)).append(";");
                                AgvErrorInfo agvErrorInfo = agvErrorInfoList.stream().filter(a ->
                                        a.getErrorInfo().equals(ob.toString())
                                ).findFirst().orElse(new AgvErrorInfo());
                                if (StringUtils.isNullOrEmpty(agvErrorInfo.getDeviceId())) {
                                    agvErrorInfo = new AgvErrorInfo();
                                    agvErrorInfo.setDeviceId(device_id);
                                    agvErrorInfo.setErrorInfo(ob.toString());
                                    agvErrorInfo.setCreateTime(new Date());
                                    agvTasksMapper.insertAgvErrorInfo(agvErrorInfo);
                                }
                            }
                            // 如果这次上报的异常中没有上次的异常了，则把上次的异常都标记已修复
                            List<Object> finalException = exception;
                            agvErrorInfoList = agvErrorInfoList.stream().filter(a -> !finalException.contains(a.getErrorInfo())).collect(Collectors.toList());
                            for (AgvErrorInfo overError : agvErrorInfoList) {
                                agvTasksMapper.updateAgvErrorInfoByIdAndErrorInfo(device_id, overError.getErrorInfo());
                            }

                        } else {
                            agvTasksMapper.updateAgvErrorInfoById(device_id);
                        }
                    }catch (Exception ex){
                        log.info("agv异常信息处理失败：{}",ex.getMessage());
                    }

                    // 查找每辆车的任务
                    String startPoint = "";
                    int taskCount = 0;
                    int errorCount = 0;

                    LocalDate today = LocalDate.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    String toDay = today.format(formatter);

                    // 计算每台车的故障率

//                    switch (device_id){
//                        case "1":
//                            // 5车间2楼 送到ZD1 或者从 ZD1取货
//                            taskCount = agvTasksHisMapper.selectList(new LambdaQueryWrapper<AgvTasksHis>()
//                                    .apply(" DATA(createdTime) = {0}",toDay)
//                                    .and(wapper->wapper
//                                            .like(AgvTasksHis::getStartpointcode,"ZD1")
//                                            .or()
//                                            .like(AgvTasksHis::getEndpointcode,"ZD1")
//                                    )
//                            ).size();
//                            errorCount = agvTasksMapper.getTodayAgvErrorInfoListById(device_id,toDay).size();
//                            taskCount = Math.max(taskCount, 1);
//                            if(errorCount>0){
//                                double gzl = (double) errorCount/taskCount;
//                                fault_rate = (int) gzl * 100;
//                            }
//                            break;
//                        case "2":
//                            // 1车间2楼 送到 CMHC 或者 ZC 开头的货位上，或者从 CMHC 或者 ZC 开头的货位上取货
//                            taskCount = agvTasksHisMapper.selectList(new LambdaQueryWrapper<AgvTasksHis>()
//                                    .apply(" DATA(createdTime) = {0}",toDay)
//                                    .and(wapper->wapper
//                                            .like(AgvTasksHis::getEndpointcode,"CMHC")
//                                            .or()
//                                            .like(AgvTasksHis::getEndpointcode,"ZC")
//                                            .or()
//                                            .like(AgvTasksHis::getStartpointcode,"CMHC")
//                                            .or()
//                                            .like(AgvTasksHis::getStartpointcode,"ZC")
//                                    )
//                            ).size();
//                            errorCount = agvTasksMapper.getTodayAgvErrorInfoListById(device_id,toDay).size();
//                            taskCount = Math.max(taskCount, 1);
//                            if(errorCount>0){
//                                double gzl = (double) errorCount/taskCount;
//                                fault_rate = (int) gzl * 100;                            }
//                            break;
//                        case "3":
//                            // 1车间1楼  从 GWSL 或者 GWXL 开始的位置取货
//                            taskCount = agvTasksHisMapper.selectList(new LambdaQueryWrapper<AgvTasksHis>()
//                                    .apply(" DATA(createdTime) = {0}",toDay)
//                                    .and(wapper->wapper
//                                            .like(AgvTasksHis::getStartpointcode,"GWSL")
//                                            .or()
//                                            .like(AgvTasksHis::getStartpointcode,"GWXL")
//                                    )
//                            ).size();
//                            errorCount = agvTasksMapper.getTodayAgvErrorInfoListById(device_id,toDay).size();
//                            taskCount = Math.max(taskCount, 1);
//                            if(errorCount>0){
//                                double gzl = (double) errorCount/taskCount;
//                                fault_rate = (int) gzl * 100;                            }
//
//                            break;
//                        case "4":
//                            // 5车间1楼 从 HCW开头 的货位取货
//                            taskCount = agvTasksHisMapper.selectList(new LambdaQueryWrapper<AgvTasksHis>()
//                                    .apply(" DATA(createdTime) = {0}",toDay)
//                                    .and(wapper->wapper
//                                            .like(AgvTasksHis::getStartpointcode,"HCW")
//                                    )
//                            ).size();
//                            errorCount = agvTasksMapper.getTodayAgvErrorInfoListById(device_id,toDay).size();
//                            taskCount = Math.max(taskCount, 1);
//                            if(errorCount>0){
//                                double gzl = (double) errorCount/taskCount;
//                                fault_rate = (int) gzl * 100;
//                            }
//                            break;
//                    }

                    // 计算总故障率
                    taskCount = agvTasksHisMapper.selectList(new LambdaQueryWrapper<AgvTasksHis>()
                          .apply(" DATA(createdTime) = {0}",toDay)
                    ).size();
                    errorCount = agvTasksMapper.getTodayAgvErrorInfoList(toDay).size();
                    taskCount = Math.max(taskCount, 1);
                    if(errorCount>0){
                        double gzl = (double) errorCount/taskCount;
                        fault_rate = (int) gzl * 100;
                    }

                    GetAgvinfo agvinfo = agvInfoList.stream().filter(a->a.getDeviceId().equals(device_id)).findFirst().orElse(new GetAgvinfo());
                    agvinfo.setDeviceId(device_id);
                    agvinfo.setDeviceName(device_name);
                    agvinfo.setDeviceIp(device_ip);
                    agvinfo.setMapId(map_id);
                    agvinfo.setMapName(map_name);
                    agvinfo.setAreaId(area_id);
                    agvinfo.setBatteryPercentile(Long.parseLong(battery_percentile));
                    agvinfo.setState(state);
                    agvinfo.setStateId(state_id);
                    agvinfo.setX(Double.parseDouble(x));
                    agvinfo.setY(Double.parseDouble(y));
                    agvinfo.setTheta(Double.parseDouble(theta));
                    agvinfo.setExceptionLevel(level);

                    agvinfo.setException(errorInfo.toString());

                    if(agvinfo.getDeviceId()!=null){
                        agvTasksMapper.updateAgvInfo(agvinfo);
                    }else{
                        agvTasksMapper.insertAgvInfo(agvinfo);
                    }

                }

                if (jsonData.getData() != null) {

                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
            log.info("获取agv信息异常：{}",ex.getMessage());
        }
    }
}
